<script setup>
import { ref, computed, watch, onMounted } from 'vue';
import { hexToRgb, rgbToHex, hslToRgb } from './utils';

const props = defineProps({
  modelValue: {
    type: [String, Object],
    default: ''
  },
  defaultColor: {
    type: String,
    default: '#000000'
  },
  showAlpha: {
    type: Boolean,
    default: false
  },
  presetColors: {
    type: Array,
    default: () => ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#00ffff', '#ff00ff']
  },
  colorMode: {
    type: String,
    default: 'hex'
  },
  disabled: {
    type: Boolean,
    default: false
  }
});

const emit = defineEmits(['update:modelValue', 'change', 'invalid']);

const currentColor = ref(props.modelValue || props.defaultColor);
const hue = ref(0);
const saturation = ref(100);
const lightness = ref(50);
const alpha = ref(100);

const colorPanelRef = ref(null);
const hueSliderRef = ref(null);

const updateColor = (h, s, l, a = 100) => {
  hue.value = h;
  saturation.value = s;
  lightness.value = l;
  alpha.value = a;
  
  const rgb = hslToRgb(h/360, s/100, l/100);
  const hex = rgbToHex(rgb.r, rgb.g, rgb.b);
  
  currentColor.value = hex;
  emit('update:modelValue', hex);
  emit('change', hex);
};

const handleColorPanelClick = (event) => {
  if (props.disabled) return;
  
  const rect = event.target.getBoundingClientRect();
  const x = event.clientX - rect.left;
  const y = event.clientY - rect.top;
  
  const s = Math.round((x / rect.width) * 100);
  const l = Math.round(100 - (y / rect.height) * 100);
  
  updateColor(hue.value, s, l);
};

const handleHueSliderChange = (event) => {
  if (props.disabled) return;
  
  const rect = event.target.getBoundingClientRect();
  const x = event.clientX - rect.left;
  const h = Math.round((x / rect.width) * 360);
  
  updateColor(h, saturation.value, lightness.value);
};

const handlePresetColorClick = (color) => {
  if (props.disabled) return;
  currentColor.value = color;
  emit('update:modelValue', color);
  emit('change', color);
};

onMounted(() => {
  if (!props.modelValue && props.defaultColor) {
    currentColor.value = props.defaultColor;
    emit('update:modelValue', props.defaultColor);
  }
});

watch(() => props.modelValue, (newVal) => {
  if (newVal !== currentColor.value) {
    currentColor.value = newVal;
  }
});
</script>

<template>
  <div class="color-picker" :class="{ 'is-disabled': disabled }">
    <div class="color-display">
      <div class="current-color" :style="{ backgroundColor: currentColor }"></div>
    </div>
    
    <div class="color-panel" 
         ref="colorPanelRef"
         @click="handleColorPanelClick">
      <div class="saturation-lightness-panel"
           :style="{ backgroundColor: `hsl(${hue}, 100%, 50%)` }">
      </div>
    </div>
    
    <div class="hue-slider" 
         ref="hueSliderRef"
         @click="handleHueSliderChange">
      <div class="hue-track"></div>
      <div class="hue-thumb" 
           :style="{ left: `${(hue/360)*100}%` }">
      </div>
    </div>
    
    <div v-if="showAlpha" class="alpha-slider">
      <input type="range" 
             v-model="alpha" 
             min="0" 
             max="100"
             :disabled="disabled">
    </div>
    
    <div class="preset-colors">
      <div v-for="color in presetColors" 
           :key="color"
           class="preset-color"
           :style="{ backgroundColor: color }"
           @click="handlePresetColorClick(color)">
      </div>
    </div>
    
    <div class="color-inputs">
      <input type="text" 
             v-model="currentColor"
             :disabled="disabled"
             @input="$emit('update:modelValue', $event.target.value)">
    </div>
  </div>
</template>

<style scoped>
.color-picker {
  width: 100%;
  padding: 15px;
  background: #fff;
  border: 1px solid #ddd;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.color-display {
  margin-bottom: 10px;
}

.current-color {
  width: 100%;
  height: 30px;
  border-radius: 4px;
  border: 1px solid #ddd;
}

.color-panel {
  width: 100%;
  height: 150px;
  position: relative;
  margin-bottom: 10px;
  border: 1px solid #ddd;
  cursor: pointer;
}

.saturation-lightness-panel {
  width: 100%;
  height: 100%;
  background-image: 
    linear-gradient(to right, #fff, transparent),
    linear-gradient(to top, #000, transparent);
}

.hue-slider {
  width: 100%;
  height: 20px;
  position: relative;
  margin-bottom: 10px;
  cursor: pointer;
}

.hue-track {
  width: 100%;
  height: 100%;
  background: linear-gradient(to right, 
    #ff0000 0%, #ffff00 17%, 
    #00ff00 33%, #00ffff 50%, 
    #0000ff 67%, #ff00ff 83%, 
    #ff0000 100%);
  border-radius: 4px;
}

.hue-thumb {
  position: absolute;
  width: 4px;
  height: 100%;
  background: #fff;
  border: 1px solid #999;
  top: 0;
  transform: translateX(-50%);
}

.preset-colors {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-bottom: 10px;
}

.preset-color {
  width: 20px;
  height: 20px;
  border-radius: 4px;
  border: 1px solid #ddd;
  cursor: pointer;
}

.color-inputs input {
  width: 100%;
  padding: 5px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.is-disabled {
  opacity: 0.6;
  pointer-events: none;
}

.alpha-slider {
  width: 100%;
  margin-bottom: 10px;
}

.alpha-slider input {
  width: 100%;
}
</style> 